home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / timer11.zip / MAKEUTIL.ZIP / FOREACH.C < prev    next >
C/C++ Source or Header  |  1992-04-18  |  4KB  |  157 lines

  1. /****************************************************************************
  2. *
  3. *                                Foreach
  4. *
  5. *                    Copyright (C) 1991 Kendall Bennett.
  6. *                            All rights reserved.
  7. *
  8. * Filename:        $RCSfile: foreach.c $
  9. * Version:        $Revision: 1.1 $
  10. *
  11. * Language:        ANSI C
  12. * Environment:    MS DOS
  13. *
  14. * Description:    Program to execute the same command for a number of
  15. *                different files. The list of files is passed in via a
  16. *                simple text file. We try to fit as many files on the
  17. *                command line as possible (120 chars max for MS DOS
  18. *                compatibility).
  19. *
  20. * $Id: foreach.c 1.1 92/04/18 17:26:05 kjb Exp $
  21. *
  22. * Revision History:
  23. * -----------------
  24. *
  25. * $Log:    foreach.c $
  26. * Revision 1.1  92/04/18  17:26:05  kjb
  27. * Initial revision
  28. ****************************************************************************/
  29.  
  30. #include <stdio.h>
  31. #include <malloc.h>
  32. #include <process.h>
  33. #include <string.h>
  34. #include <ctype.h>
  35.  
  36. #ifdef __MSDOS__
  37. #include <dir.h>
  38. #endif
  39.  
  40. #define    MAX_FILES        200            /* 200 files maximum                */
  41. #define    MAXLINELEN        120            /* 128 chars to a command line        */
  42.  
  43. #define    true            1
  44. #define    false            0
  45.  
  46. /*------------------------- Global variables ------------------------------*/
  47.  
  48. char    *rcsid = "$Id: foreach.c 1.1 92/04/18 17:26:05 kjb Exp $";
  49. char    *filenames[MAX_FILES];
  50.  
  51. /* Adjust the size of the default stack and heap so that we dont take
  52.  * up too much memory from the child process. A small stack of 256 bytes
  53.  * should be enough, and a heap of 5k should suffice to hold the list of
  54.  * names to process.
  55.  */
  56.  
  57. extern unsigned    _stklen        = 256;
  58. extern unsigned _heaplen    = 5*1024;
  59.  
  60. /* Open a file returning true if successful */
  61.  
  62. int openfile(FILE **in,char *filename,char *mode)
  63. {
  64.     if( (*in = fopen(filename,mode) ) == NULL) {
  65.         return false;    /* Open failed                                    */
  66.         }
  67.     else
  68.         return true;    /* Open was successful                            */
  69. }
  70.  
  71. void readfilenames(char *name,char *filenames[],int *numfiles)
  72. /****************************************************************************
  73. *
  74. * Function:        readfilenames
  75. * Parameters:    name        - Name of file to read filenames from
  76. *                filenames[]    - Array to place filenames in
  77. *                numfiles    - Number of filenames read
  78. *
  79. * Description:    Reads the names of the files to translate from the
  80. *                specified file 'name'. We expect each file name to we
  81. *                a whole word on the line and ignore all whitespace.
  82. *
  83. ****************************************************************************/
  84. {
  85.     char    buf[MAXPATH];
  86.     FILE    *f;
  87.  
  88.     if (!openfile(&f,name,"rt")) {
  89.         printf("Unable to open the file: %s\n",name);
  90.         exit(1);
  91.         }
  92.  
  93.     *numfiles = 0;
  94.     while (!feof(f) && (fscanf(f," %s ",buf) == 1)) {
  95.         filenames[*numfiles] = strdup(buf);
  96.         (*numfiles)++;
  97.         }
  98.  
  99.     fclose(f);
  100. }
  101.  
  102. int main(int argc,char *argv[])
  103. {
  104.     char    prefix[MAXLINELEN];
  105.     char    command[MAXLINELEN];
  106.     int        i,numfiles,length,totallength,prefixlength;
  107.     int        group = true;
  108.  
  109.     if (strcmp(argv[1],"-nogroup") == 0) {
  110.         group = false;
  111.         argv++;
  112.         argc--;
  113.         }
  114.  
  115.     if (argc != 3) {
  116.         printf("Usage: foreach [-nogroup] \"command\" <filelist>\n\n");
  117.         printf("where <filelist> is the name of a file containing the\n");
  118.         printf("filenames for excute command on. If -nogroup is specified\n");
  119.         printf("the command is executed once for every file in <filelist>, otherwise\n");
  120.         printf("the filenames are grouped together on the command line.\n");
  121.         exit(1);
  122.         }
  123.  
  124.     strcpy(prefix,argv[1]);
  125.     prefixlength = strlen(prefix);
  126.     readfilenames(argv[2],filenames,&numfiles);
  127.  
  128.     /* Execute command once for every file in the list */
  129.  
  130.     for (i = 0; i < numfiles;) {
  131.         strcpy(command,prefix);
  132.         totallength = prefixlength;
  133.         while (totallength < MAXLINELEN && i < numfiles) {
  134.             if ((length = strlen(filenames[i])) == 0) {
  135.                 i++;
  136.                 continue;
  137.                 }
  138.             if ((totallength += length+1) < MAXLINELEN) {
  139.                 strcat(command," ");
  140.                 strcat(command,filenames[i++]);
  141.                 }
  142.             if (!group)
  143.                 break;
  144.             }
  145.         printf(command);
  146.         printf("\n");
  147.  
  148.         if (system(command)) {
  149.             perror("Command failed: ");
  150.             exit(1);
  151.             }
  152.         }
  153.  
  154.     return 0;
  155. }
  156.